package gqz.mvvm.view.custom;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PointF;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;

import gqz.mvvm.R;

/**
 * Created by Administrator on 2018/3/17.
 */

public class MatrixView extends View {

    private String TAG = "MatrixView-->";

    private float mWidth = 0, mHeight = 0, mHalfW = 0, mHalfH = 0;

    private Paint mPaint;
    private Matrix mMatrix;
    private Bitmap mBmp;

    private RectF[] rects = new RectF[5];
    private float[] src = new float[8], dst = new float[8];
    private int pointCount = 1, triggerRadius = 50;//触发半径

    public MatrixView(Context context) {
        super(context);
        init();
    }

    public MatrixView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public MatrixView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    private void init() {
        Log.i(TAG, "init: ");
        setClickable(true);
        mMatrix = new Matrix();

        mPaint = new Paint();
        mPaint.setAntiAlias(true);
        mPaint.setDither(true);
        mPaint.setStrokeWidth(3);
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setStrokeCap(Paint.Cap.ROUND);
        mPaint.setStrokeJoin(Paint.Join.ROUND);
        mPaint.setColor(Color.LTGRAY);

        mBmp = BitmapFactory.decodeResource(getResources(), R.drawable.liyings);
    }

    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        super.onLayout(changed, left, top, right, bottom);
        Log.i(TAG, "onLayout: ");
        mWidth = getWidth();
        mHeight = getHeight();

        mHalfW = mWidth / 2;
        mHalfH = mHeight / 2;
        Log.i(TAG, "w=" + mWidth + " h=" + mHeight + " hw=" + mHalfW + " hh=" + mHalfH);

        for (int i = 0; i < rects.length; i++) {
            float lx = i * 100 + 20, ly = mHeight - 50;
            float rx = i * 100 + 100, ry = mHeight;
            rects[i] = new RectF(lx, ly, rx, ry);
        }

//        mMatrix.setTranslate(mHalfW - mBmp.getWidth() / 2, mHalfH - mBmp.getHeight() / 2);

        float[] temp = {
                0, 0,
                mBmp.getWidth(), 0,
                mBmp.getWidth(), mBmp.getHeight(),
                0, mBmp.getHeight()
        };
        src = temp.clone();
        dst = temp.clone();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        Log.i(TAG, "onDraw: ");
        canvas.save();

        canvas.translate(50, 50);
        canvas.drawBitmap(mBmp, mMatrix, mPaint);

        float[] dst = new float[8];
        mMatrix.mapPoints(dst, src);
        mPaint.setStrokeWidth(30);
        for (int i = 0; i < pointCount * 2; i += 2) {
            canvas.drawPoint(dst[i], dst[i + 1], mPaint);
        }
        mPaint.setStrokeWidth(3);

        canvas.restore();

        for (RectF r : rects) {
            canvas.drawRect(r, mPaint);
        }
    }

    public void setMatrix() {
        /*float[] src = {//不知道为什么必须得从0开始
                0, 0, //左上角x,y
                mBmp.getWidth(), 0, //右上角x,y
                mBmp.getWidth(), mBmp.getHeight(), //右下角x,y
                0, mBmp.getHeight()//左下角x,y
        };//原来的坐标,即矩形的四个顶点的坐标,***顺序为顺时针，切记不要搞错位置***
        float[] dst = {
                mHalfW - mBmp.getWidth() / 2, mHalfH - mBmp.getHeight() / 2,
                mHalfW + mBmp.getWidth() / 2, mHalfH - mBmp.getHeight() / 2 + 50,
                mHalfW + mBmp.getWidth() / 2, mHalfH + mBmp.getHeight() / 2 - 50,
                mHalfW - mBmp.getWidth() / 2, mHalfH + mBmp.getHeight() / 2
        };//目标坐标,右侧边长将会缩短*/
        int srcIndex = 0;
        int dstIndex = 0;
        pointCount = src.length >> 1;//为0，则还原
        mMatrix.setPolyToPoly(src, srcIndex, dst, dstIndex, pointCount);
        invalidate();
    }

    private boolean mClickMode = false;
    private int mClickRectIndex = 0;

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                for (int i = 0; i < rects.length; i++) {
                    if (pointInRect(new PointF(event.getX(), event.getY()), rects[i])) {
                        mClickMode = true;
                        mClickRectIndex = i;
                    }
                }
                break;
            case MotionEvent.ACTION_MOVE:
                float x = event.getX() - 50, y = event.getY() - 50;
                if (!mClickMode) {
                    for (int i = 0; i < pointCount * 2; i += 2) {
                        if (Math.abs(x - dst[i]) <= triggerRadius && Math.abs(y - dst[i + 1]) <= triggerRadius) {
                            dst[i] = x;
                            dst[i + 1] = y;
                            resetPolyMatrix(pointCount);
                            break;// 防止两个点的位置重合
                        }
                    }
                }
                break;
            case MotionEvent.ACTION_UP:
                if (mClickMode) {
                    dst = src.clone();
                    resetPolyMatrix(mClickRectIndex);
                    mClickMode = false;
                }
                break;
        }
        return super.onTouchEvent(event);
    }

    public void resetPolyMatrix(int pointCount) {
        this.pointCount = pointCount;
        mMatrix.reset();
        // 核心要点
        mMatrix.setPolyToPoly(src, 0, dst, 0, pointCount);
        invalidate();
    }

    private boolean pointInRect(PointF point, RectF rectf) {
        float x = point.x, y = point.y;
        if (x > rectf.left && x < rectf.right)
            if (y > rectf.top && y < rectf.bottom)
                return true;
        return false;
    }

    private boolean pointInCircle(PointF point, Circle c) {
        float x = point.x, y = point.y;
        if (Math.abs(x - c.x) <= c.r)
            if (Math.abs(y - c.y) <= c.r)
                return true;
        return false;
    }

    class Circle {
        public float x = 0;
        public float y = 0;
        public float r = 0;

        public Circle(float x, float y, float r) {
            this.x = x;
            this.y = y;
            this.r = r;
        }
    }
}
